package cn.agiledata.bank.transaction.action;

import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;

import cn.agiledata.bank.common.util.Constant;
import cn.agiledata.bank.common.util.ConvertUtil;
import cn.agiledata.bank.common.util.ForeDict;
import cn.agiledata.bank.hibernateBean.Account;
import cn.agiledata.bank.hibernateBean.Bank;
import cn.agiledata.bank.hibernateBean.BankInfo;
import cn.agiledata.bank.hibernateBean.ScoresHis;
import cn.agiledata.bank.hibernateBean.Transaction;
import cn.agiledata.bank.linkbank.action.WebPayRequestAction;
import cn.agiledata.bank.linkbank.logic.payment.UnsPayResponse;
import cn.agiledata.bank.linkbank.service.WebPayService;
import cn.agiledata.bank.scores.service.IScoresService;
import cn.agiledata.bank.scores.service.ScoresFactory;
import cn.agiledata.bank.transaction.exception.TransactionException;
import cn.agiledata.bank.transaction.form.MultiStepForm;
import cn.agiledata.bank.transaction.form.OnlineInpourForm;
import com.vnv.infrastructure.logic.IPBAppFactory;

/**
 * 在线充值
 * 
 * @author maxianbo
 * 
 */
public abstract class OnlineInpourAction extends InpourAction {

    protected final WebPayService getWebPayService() {
        return (WebPayService) IPBAppFactory.getObj(ForeDict.SERVICE_WEB_PAY);
    }

    /**
     * 校验选择的银行id是否有效
     */
    private void validateBank(long bankId) throws TransactionException {
        if (bankId <= 0) {
            throw TransactionException.NOT_SELECT_BANK;
        }
    }

    public final ActionForward assign(ActionMapping mapping,
            ActionForm actionForm, HttpServletRequest request,
            HttpServletResponse response) throws Exception {
        MultiStepForm form = (MultiStepForm) actionForm;
        int step = form.getStep();
        ActionForward forward;
        switch (step) {
        case 0: // 第0步准备初始化数据
            forward = prepare(mapping, actionForm, request, response);
            break;
        case 1: // 第1步填写充值信息
            forward = fill(mapping, actionForm, request, response);
            break;
        case 2: // 第2步进行充值操作
            forward = inpour(mapping, actionForm, request, response);
            break;
        case 3: // 第3步确认充值交易，显示充值结果
            forward = showResult(mapping, actionForm, request, response);
            break;
        default: // 其它步骤序数跳转到第0步，进入新的充值流程，防止错误的步骤序数被提交
            form.setStep(0);
            forward = prepare(mapping, actionForm, request, response);
        }
        // 设置新的步骤序数，最大步骤序数为3
        form.setNextStep(3);
        return forward;
    }

    /**
     * 
     * @return 银行列表
     */
    protected abstract Bank[] getBankList();

    public ActionForward prepare(ActionMapping mapping, ActionForm actionForm,
            HttpServletRequest request, HttpServletResponse response)
            throws Exception {
        ActionForward forward = super.prepare(mapping, actionForm, request,
                response);
        loadBankList(request);
        return forward;
    }

    public ActionForward fill(ActionMapping mapping, ActionForm actionForm,
            HttpServletRequest request, HttpServletResponse response)
            throws Exception {
        ActionForward forward = super.fill(mapping, actionForm, request,
                response);
        if (hasAppExceptionMessage(request)) { // 如果存在异常信息，重新加载银行列表
            loadBankList(request);
        } else { // 如果不存在异常信息，加载选择的银行信息
            OnlineInpourForm form = (OnlineInpourForm) actionForm;
            // 选择的银行
            String bankId = String.valueOf((form.getBankId()));
            BankInfo bank = getCommonService().getBankInfo(bankId);
            request.setAttribute("bank", bank);
        }
        return forward;
    }

    /**
     * 加载银行列表
     */
    private void loadBankList(HttpServletRequest request) {
        Bank[] banks = getBankList();
        if (isCorpAccount(request)) { // 企业客户充值只显示支持b2c的银行
            List bankList = new ArrayList(banks.length);
            for (int i = 0; i < banks.length; i++) {
                if (banks[i].isB2bSupported()) {
                    bankList.add(banks[i]);
                }
            }
            request.setAttribute("BankList", bankList);
        } else {
            request.setAttribute("BankList", banks);
        }
    }

    public ActionForward inpour(ActionMapping mapping, ActionForm actionForm,
            HttpServletRequest request, HttpServletResponse response)
            throws Exception {
        if (!isTokenValid(request)) {
            throw TransactionException.REPEATEDLY_SUBMIT;
        }
        OnlineInpourForm form = (OnlineInpourForm) actionForm;
        validateAmount(form.getAmount());
        validateBank(form.getBankId());
        // Transaction trans = createTransaction(form);
        // try {
        // saveTransaction(trans);
        // } catch (RuntimeException e) {
        // throw TransactionException.INPOUR_FAILED;
        // }
        // request.setAttribute("transactionId", trans.getTransId());
        resetToken(request);
        request.getSession().removeAttribute(WebPayRequestAction.UNS_PAY_REQUEST);
        return mapping.findForward("requestBank");
    }

    /**
     * 显示积分
     */
    private void showScore(HttpServletRequest request, Account inpourAccount,Long transId) {
        IScoresService scoreService = ScoresFactory.getScoresService();
        String url = ConvertUtil.getRequestURL(request);
        if (Constant.ACCOUNT_TYPE_BUYER.equals(inpourAccount.getAccountType())) {
            ScoresHis sh = scoreService.getScoresHis(inpourAccount.getId(),
                    Constant.SCORES_SOURCE_D, transId);
            if (Constant.SCORES_ACTIVATE_STATUS_A.equals(inpourAccount
                    .getActivateStatus())) {
                scoreService.setActivationStatus(inpourAccount.getId(), url);
            }
            request.setAttribute("ScoresHistory", sh);
        }
    }

    /**
     * 显示充值结果
     */
    public ActionForward showResult(ActionMapping mapping,
            ActionForm actionForm, HttpServletRequest request,
            HttpServletResponse response) throws Exception {
        OnlineInpourForm form = (OnlineInpourForm) actionForm;
        Transaction trans = getTransactionTemplate().getTransactionByTranId(
                form.getOrderId());
        request.setAttribute("transaction", trans);
        request.setAttribute("actualAmount", getActualInpourAmount(trans));
        request.setAttribute("personAccount", new Boolean(
                !isCorpAccount(request)));

        // 积分显示
        Account inpourAccount = trans.getCredit().getAccount();
        // zln 修正 2008-1-22 将交易ID作为参数进行积分历史查询，
        // 以修正无积分规则进行充值时每次会显示最后一条充值历史内容的促无哦
        showScore(request, inpourAccount,trans.getId());

        return mapping.findForward(ForeDict.FORWARD_STEP_3);
    }
}
